// 2015年版权所有etcd作者
// 
// 根据Apache许可证2.0版（以下简称“许可证”）获得许可；
// 除非遵守许可证，否则不得使用此文件。
// 您可以通过
// 
// www.apache.org/licenses/LICENSE-2.0 
// 
// 除非适用法律要求或书面同意，否则根据许可证分发的软件
// 按“原样”分发，
// 无任何明示或暗示的保证或条件。
// 请参阅许可证，了解管理许可的特定语言和
// 许可证下的限制。

package transport

import (
	"net"
	"net/http"
	"time"
)

// NewTimeoutTransport返回使用给定TLS信息创建的传输。
// 如果对创建的连接块的读写时间超过其时间限制，
// 将返回超时错误。
// 如果设置了读/写超时，则传输将无法重新使用连接。
func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time.Duration) (*http.Transport, error) {
	tr, err := NewTransport(info, dialtimeoutd)
	if err != nil {
		return nil, err
	}

	if rdtimeoutd != 0 || wtimeoutd != 0 {
		// 超时连接在空闲后不久将超时。
		// 不应将其作为空闲连接放回http传输，以备将来使用。
		tr.MaxIdleConnsPerHost = -1
	} else {
		// 允许对等方之间有更多空闲连接，以避免不必要的端口分配。
		tr.MaxIdleConnsPerHost = 1024
	}

	tr.Dial = (&rwTimeoutDialer{
		Dialer: net.Dialer{
			Timeout:   dialtimeoutd,
			KeepAlive: 30 * time.Second,
		},
		rdtimeoutd: rdtimeoutd,
		wtimeoutd:  wtimeoutd,
	}).Dial
	return tr, nil
}
